package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.AnnualySharePriceData;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Company;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.AnnualPriceDataService;
import org.sixtynine.stock.service.CompanyService;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.service.file.ExcelProcessorFactory;
import org.sixtynine.stock.service.file.FileDataService;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan this class handle daily share data
 */

@Controller
@SessionAttributes
public class AnnualPriceDataController extends PriceDataController {

	@Autowired
	private GenericService genericService;

	@Autowired
	private AnnualPriceDataService annualPriceDataService;

	@Autowired
	private FileDataService fileDataService;

	@Autowired
	DataManagerService dataManagerService;

	@Autowired
	CompanyService companyService;

	private static final String BIND_VAL_ANNUAL_SHARE_DATA = "annualySharePriceData";

	@RequestMapping(value = "/admin/annualpricedata/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {
		return super.search(criteria, request);
	}

	@Override
	protected String getPage() {
		return "/admin/annualpricedata/list";
	}

	@Override
	protected void setPageData(int companyId, Date fromDate, Date toDate,
			String sortByFirst, String sortBySecond, GridPramDTO gridPramDTO,
			ModelAndView modelAndView) {
		Page<AnnualySharePriceData> sharePage = annualPriceDataService
				.searchAnnualySharePriceData(companyId, fromDate, toDate, null,
						null, gridPramDTO);

		modelAndView.addObject("annualySharePriceDataPage", sharePage);
	}

	@RequestMapping(value = "/admin/annualpricedata/add")
	public ModelAndView addAnnualPriceData(HttpServletRequest request) {

		ModelAndView modelAndView = new ModelAndView(getAddPage());

		bindDummyObject(modelAndView);
		bindCompanyList(modelAndView);
		bindFileUpload(modelAndView);

		return modelAndView;
	}

	@Override
	protected String getExelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_ANNUAL_PRICE_DATA_LIST;
	}

	@RequestMapping(value = "/admin/annualpricedata/add/file_process")
	public ModelAndView addingAnnualySharePriceDataByFile(
			HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return addShareByFile(request, uploadFile);
	}

	@RequestMapping(value = "/admin/annualpricedata/add/company_process")
	public ModelAndView addingAnnualySharePriceDataByCompany(
			HttpServletRequest request,
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		return processShareDataByCompany(uploadFile);
	}

	@RequestMapping(value = "/admin/annualpricedata/add/process")
	public ModelAndView addingAnnualySharePriceData(
			@Valid @ModelAttribute AnnualySharePriceData annualPriceData,
			BindingResult result) {

		ModelAndView modelAndView = null;

		if (DateUtil.checkFutureDate(annualPriceData.getDate())) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "You can't add a future date. Please enter a current or past record.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			return modelAndView;
		}

		// check monthly sector data exsist
		Criterion compleateCriterion = Restrictions.between("date",
				DateUtil.getYearStart(annualPriceData.getDate()),
				DateUtil.getYearEnd(annualPriceData.getDate()));

		List<BaseEntity> dataList = genericService.findByCriteria(
				compleateCriterion, AnnualySharePriceData.class);
		if (dataList.size() > 0) {
			modelAndView = new ModelAndView(getAddPage());
			String message = "Data already exists for ."
					+ annualPriceData.getDate();
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			modelAndView.addObject("userLogged", true);
		}

		if (!result.hasErrors()) {
			genericService.saveOrUpdate(annualPriceData);
			modelAndView = new ModelAndView(getPage());

			String message = "Data is successfully inserted.";
			modelAndView.addObject(BIND_VAL_MESSAGE, message);
			loadData(1, -1, annualPriceData.getCompany().getId(), null,
					annualPriceData.getDate(), annualPriceData.getDate(),
					modelAndView, null);

		} else {
			modelAndView = new ModelAndView(getAddPage());
			bindDummyObject(modelAndView);
			bindCompanyList(modelAndView);
			bindFileUpload(modelAndView);
		}
		return modelAndView;

	}

	protected void bindFileUpload(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_FILE_UPLOAD, new FileUploadForm());
	}

	protected void bindDummyObject(ModelAndView modelAndView) {
		modelAndView.addObject(BIND_VAL_ANNUAL_SHARE_DATA,
				new AnnualySharePriceData());

	}

	@RequestMapping(value = "/admin/annualpricedata/list")
	public ModelAndView listOfAnnualySharePriceData(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {

		return showList(request, page, totalRecords);
	}

	@RequestMapping(value = "/admin/annualpricedata/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editAnnualySharePriceData(HttpServletRequest request,
			@PathVariable Integer id) {
		return showEdit(id);
	}

	@RequestMapping(value = "/admin/annualpricedata/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingAnnualySharePriceData(
			@Valid @ModelAttribute("annualySharePriceData") AnnualySharePriceData annualySharePriceData,
			BindingResult result) {

		return editShareData(annualySharePriceData, result);
	}

	@RequestMapping(value = "/admin/annualpricedata/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteAnnualySharePriceData(@PathVariable Integer id) {

		return deleteShareData(id);
	}

	@RequestMapping(value = "/admin/annualpricedata/delete/selected", method = RequestMethod.POST)
	public ModelAndView deleteSelectedAnnualSharePriceData(
			HttpServletRequest request,
			@RequestParam(value = "deleteIds", required = false) Integer[] deleteIds) {
		return deleteSelected(deleteIds);
	}

	@RequestMapping(value = "/admin/annualpricedata/deleteFiltered")
	public ModelAndView deleteFilteredAnnualSharePriceData(
			HttpServletRequest request) {
		ModelAndView modelAndView = new ModelAndView(
				"admin/annualpricedata/list");

		SessionBean sBean = SessionBean.getInstance(request);
		LoadingSearchCriteria criteria = (LoadingSearchCriteria) sBean
				.getAttr(SEARCH_CRITERIA);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();
		}

		if (criteria.getCompanyId() == 0) {
			criteria.setCompanyId(-1);
		}

		if (criteria.getCompanyName() != null
				&& !criteria.getCompanyName().isEmpty()) {

			Company company = companyService.findCompany(
					criteria.getCompanyName(), criteria.getCompanyId());

			if (company != null) {
				criteria.setCompanyId(company.getId());
			} else {
				criteria.setCompanyId(-1);
			}
		}

		// delete the selected criteria
		annualPriceDataService.deleteAnnualySharePriceData(
				criteria.getCompanyId(), criteria.getFromDate(),
				criteria.getToDate());

		// reload the page and set message
		String message = "Successfully deleted filted data.";
		modelAndView.addObject(BIND_VAL_MESSAGE, message);

		loadData(1, -1, -1, null, null, null, modelAndView, criteria);
		return modelAndView;
	}

	@Override
	protected Class getBaseClass() {
		return AnnualySharePriceData.class;
	}

	@Override
	protected String getEditPage() {
		return "/admin/annualpricedata/edit";
	}

	@Override
	protected void loadData(Integer page, Integer totalRecords,
			BaseEntity shareData, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		AnnualySharePriceData annualySharePriceData = (AnnualySharePriceData) shareData;
		loadData(page, totalRecords,
				annualySharePriceData.getCompany().getId(), null,
				annualySharePriceData.getDate(),
				annualySharePriceData.getDate(), modelAndView, criteria);
	}

	@Override
	protected String getObjBindName() {
		return "annualySharePriceData";
	}

	@Override
	protected String getAddPage() {
		return "/admin/annualpricedata/add";
	}

	@Override
	protected String getCompanyExcelProcessorType() {
		return ExcelProcessorFactory.FILE_TYPE_COMPANY_ANNUAL_PRICE_DATA_LIST;
	}

}
